package com.semac.client.componentes.atividadestable;

import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.ActionCell.Delegate;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.google.gwt.view.client.SingleSelectionModel;
import com.semac.shared.model.Atividade;
import com.semac.shared.model.Pessoa;

public class AtividadeCellTable extends CellTable<Atividade> implements Handler, HasAtividadeEventHandlers, Delegate<Atividade> {
	private static final ProvidesKey<Atividade> KEY_PROVIDER = new ProvidesKey<Atividade>() {		
		@Override
		public Object getKey(Atividade item) {
			return item.getId();
		}
	};
	
	
	private SingleSelectionModel<Atividade> listenerSelecaoUnica = new SingleSelectionModel<Atividade>();;
	
	
	
	private TextColumn<Atividade> titulo = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			return object.getTitulo();
		}
	};
	
	private TextColumn<Atividade> descricao = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			String valor = object.getDescricao();
			if (valor != null && valor.length() > 100)
				valor = valor.subSequence(0, 100) + "...";
			return valor;
		}
	};
	
	private TextColumn<Atividade> temInscricao = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			String inscricao = "SIM";
			if (!object.isTemInscricao())
				inscricao = "NAO";
			return inscricao;
		}
	};
	
	private TextColumn<Atividade> dataIni = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			DateTimeFormat formatter = DateTimeFormat.getFormat("dd/MM/yyyy");
			if (object.getDiaDaAtividade() != null)
				return formatter.format(object.getDiaDaAtividade());
			else
				return "";
		}
	};
	
	private TextColumn<Atividade> horaIni = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			DateTimeFormat formatter = DateTimeFormat.getFormat("HH:mm");
			if (object.getDiaDaAtividade() != null)
				return formatter.format(object.getDiaDaAtividade());
			else
				return "";
		}
	};
	
	

	private TextColumn<Atividade> sala = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			if (object.getSala() == null)
				return "";
			return object.getSala();
		}
	};
	
	
	private TextColumn<Atividade> horaFim = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			DateTimeFormat formatter = DateTimeFormat.getFormat("HH:mm");
			if (object.getFimDaAtividade() == null)
				return "";
			return formatter.format(object.getFimDaAtividade());
		}
	};
	
	
	private TextColumn<Atividade> ministrantes = new TextColumn<Atividade>() {			
		@Override
		public String getValue(Atividade object) {
			String ministrantes = "";
			String virgula = "";
			for (Pessoa pessoa : object.getMinistrantes()) {
				ministrantes = ministrantes + virgula + pessoa.getNome(); 
				virgula = ", ";
			}
			return ministrantes;
		}
	};


	private Atividade atividadeSelecionada;


	private boolean edicao;


	private boolean inscricao;
	
	
	public AtividadeCellTable() {
		this.setSelectionModel(listenerSelecaoUnica);		
		this.listenerSelecaoUnica.addSelectionChangeHandler(this);
	}
	
	
	
	
	
	public AtividadeCellTable(boolean edicao, boolean inscricao) {
		super(KEY_PROVIDER);
		this.edicao = edicao;
		this.inscricao = inscricao;
		if (this.edicao && !this.inscricao)
			this.configuraTabelaParaEdicao();
		else if (this.edicao && this.inscricao)
			this.configuraParaInscricao();
		else if (!this.edicao && !this.inscricao){
			this.configuraParaVisualizacao();
		}		

		this.setSelectionModel(listenerSelecaoUnica);		
		this.listenerSelecaoUnica.addSelectionChangeHandler(this);
	}
	
	
	public void configuraPermissoes(boolean edicao, boolean inscricao){
		this.clear();
		
		this.edicao = edicao;
		this.inscricao = inscricao;
		if (this.edicao && !this.inscricao)
			this.configuraTabelaParaEdicao();
		else if (this.edicao && this.inscricao)
			this.configuraParaInscricao();
		else if (!this.edicao && !this.inscricao){
			this.configuraParaVisualizacao();
		}		
	}


	private void clear() {
		for (int i = 0 ; i < this.getColumnCount() ; i++){
			this.removeColumn(i);
		}
	}





	private void configuraParaVisualizacao() {
		this.addColumn(temInscricao, "Tem inscrição");
		this.addColumn(titulo, "Título");
		this.addColumn(descricao, "Descrição");
		this.addColumn(ministrantes, "Ministrantes");
		this.addColumn(dataIni, "Dia da atividade");
		this.addColumn(horaIni, "Hora de início");
		this.addColumn(horaFim, "Hora de término");
		this.addColumn(sala, "Sala / Laboratório");
		
		this.setColumnWidth(descricao, 60.0, Unit.PCT);
	}


	private void configuraTabelaParaEdicao() {		
		ActionCell<Atividade> actionCell = new ActionCell<Atividade>("Excluir", this);
		Column<Atividade, Atividade> column = new Column<Atividade, Atividade>(actionCell) {			
			@Override
			public Atividade getValue(Atividade object) {
				return object;
			}
		};
		
		this.addColumn(temInscricao, "Tem inscrição");
		this.addColumn(titulo, "Título");
		this.addColumn(descricao, "Descrição");
		this.addColumn(ministrantes, "Ministrantes");
		this.addColumn(dataIni, "Dia da atividade");
		this.addColumn(horaIni, "Hora de início");
		this.addColumn(horaFim, "Hora de término");
		this.addColumn(sala, "Sala / Laboratório");
		this.addColumn(column, "Exclusão");
		
		
		this.setColumnWidth(descricao, 60.0, Unit.PCT);
		this.setColumnWidth(column, 20.0, Unit.PCT);
		
	}

	
	private void configuraParaInscricao(){

		InscricaoActionCell actionCell = new InscricaoActionCell(this);
		Column<Atividade, Atividade> column = new Column<Atividade, Atividade>(actionCell) {			
			@Override
			public Atividade getValue(Atividade object) {
				return object;
			}
		};
		
		
		this.addColumn(column, "Inscrição");
		this.addColumn(titulo, "Título");
		this.addColumn(descricao, "Descrição");
		this.addColumn(ministrantes, "Ministrantes");
		this.addColumn(dataIni, "Dia da atividade");
		this.addColumn(horaIni, "Hora de início");
		this.addColumn(horaFim, "Hora de término");
		this.addColumn(sala, "Sala / Laboratório");
		
		
		this.setColumnWidth(descricao, 60.0, Unit.PCT);
		this.setColumnWidth(column, 30.0, Unit.PCT);
		
	}
	
	
	
	
	@Override
	public void onSelectionChange(SelectionChangeEvent event) {
		 Atividade selected = this.listenerSelecaoUnica.getSelectedObject();
		 this.atividadeSelecionada = selected;
		 if (this.atividadeSelecionada != null)
			 this.fireEvent(new AtividadeCellTableSelectEvent(selected));
	}

	@Override
	public HandlerRegistration addAtividadeSelecionadaHandler(AtividadeCellTableEventHandler handler) {
		return this.addHandler(handler, AtividadeCellTableSelectEvent.TYPE);
	}
	
	@Override
	public HandlerRegistration addAtividadeDeleteHandler(AtividadeCellTableEventHandler handler) {
		return this.addHandler(handler, AtividadeCellTableDeleteEvent.TYPE);
	}

	@Override
	public HandlerRegistration addAtividadeInscreveHandler(AtividadeCellTableEventHandler handler) {
		return this.addHandler(handler, AtividadeCellTableInscreveEvent.TYPE);
	}

	
	public void cancelSelection(){
		if (this.atividadeSelecionada != null)
			this.listenerSelecaoUnica.setSelected(atividadeSelecionada, false);
		this.atividadeSelecionada = null;	
	}

	
	
	
	@Override
	public void execute(Atividade object) {
		if (this.edicao && !this.inscricao)
			this.fireEvent(new AtividadeCellTableDeleteEvent(object));
		else if (this.edicao && this.inscricao)
			this.fireEvent(new AtividadeCellTableInscreveEvent(object));	
	}


	
}
